package com.yehongyu.mytools.fileio;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

import org.apache.log4j.Logger;

public class CopyFile {
	
	/** 日志记录 */
	private final static Logger log = Logger.getLogger(CopyFile.class);
	
	private static String OUT_PATH = System.getProperty("user.dir") + "/logdir/";
	
	/**
	 * 文件拷贝过滤器
	 */
	private static class MyFileFilter implements FileFilter {
			/**
			 * 设置文件过滤
			 */
			public boolean accept(File pathname) {
				if (pathname.isDirectory()) {	//目录不过滤
					return true;
				}
				//过滤文件名后缀
				String absolutePath = pathname.getAbsolutePath();
				if(absolutePath.lastIndexOf(".")>-1){
					String suffix = absolutePath.substring(absolutePath.lastIndexOf("."));
					if (".xml".equalsIgnoreCase(suffix)) {
						return true;
					}
				}
				return false;
			}
		}
	
	/**
	 * 拷贝目录和文件（按二进制流的方式拷贝）
	 * @param src 需拷贝的文件或目录
	 * @param desDir 拷贝到的目录
	 * @return 0 未拷贝任何文件，>=1 拷贝的文件数（不包括目录）
	 */
	public static int copyFiles(String src,String desDir){
		return copyFiles(new File(src),new File(desDir));
	}

	/**
	 * 拷贝目录和文件（按二进制流的方式拷贝）
	 * @param inFile 需拷贝的文件或目录
	 * @param outDirectory 拷贝到的目录
	 * @return 0 未拷贝任何文件，>=1 拷贝的文件数（不包括目录）
	 */
	public static int copyFiles(File inFile, File outDirectory){
		if(inFile.isFile()){	//拷贝文件
			return copyFile(inFile, new File(outDirectory.getAbsolutePath(),inFile.getName()));
		}else if(inFile.isDirectory()){	//拷贝目录及目录下的所有目录和文件
			int i = 0;
			outDirectory = new File(outDirectory.getAbsolutePath(),inFile.getName());
			if (!outDirectory.exists()){
				outDirectory.mkdirs();
				if(log.isDebugEnabled()){
					log.debug("拷贝当前目录完成！从["+inFile.getPath()+"]到["+outDirectory.getPath()+"]");
				}
			}
			File[] files = inFile.listFiles(new MyFileFilter());	//设置文件过滤
			for (File f:files) {
				i += copyFiles(f,outDirectory);
			}
			return i;
		}
		return 0;
	}

	/**
	 * 拷贝单个源文件到目标文件（按二进制流的方式拷贝并覆盖）
	 * @param src 源文件
	 * @param des 目标文件
	 * @return 0 未拷贝任何文件，>=1 拷贝的文件数（不包括目录）
	 */
	private static int copyFile(File src, File des) {
		try {
			// 创建目标文件(不需要这步,加上也可以)
			if (!des.exists()) des.createNewFile();
			// 获取输入文件并设定输出文件
			InputStream in = new BufferedInputStream(new FileInputStream(src));
			OutputStream out = new BufferedOutputStream(new FileOutputStream(des));
			//设置读取缓冲区，并进行读取写入
			byte[] buffer = new byte[4096];
			int readBytes;
			while ((readBytes = in.read(buffer)) != -1) {
				out.write(buffer, 0, readBytes);
			}
			//关闭输入输出流
			out.flush();
			out.close();
			in.close();
			if(log.isDebugEnabled()){
				log.debug("拷贝当前文件完成！从["+src.getPath()+"]到["+des.getPath()+"]");
			}
		} catch (FileNotFoundException e) {
			log.error("拷贝文件时发生文件路径找不到异常，路径是src:[" + src + "]des:[" + des + "]", e);
			return 0;
		} catch (IOException e) {
			log.error("拷贝文件时发生IO异常，路径是src:[" + src + "]des:[" + des + "]", e);
			return 0;
		}
		return 1;
	}

	
	/**
	 * 拷贝目录和文件（按文本的方式拷贝）
	 * @param src 需拷贝的文件或目录
	 * @param desDir 拷贝到的目录
	 * @return 0 未拷贝任何文件，>=1 拷贝的文件数（不包括目录）
	 */
	public static int copyTextFiles(String src,String desDir){
		return copyTextFiles(new File(src),new File(desDir));
	}
	
	/**
	 * 拷贝目录和文件（按文本的方式拷贝）
	 * @param inFile 需拷贝的文件或目录
	 * @param outDirectory 拷贝到的目录
	 * @return 0 未拷贝任何文件，>=1 拷贝的文件数（不包括目录）
	 */
	public static int copyTextFiles(File inFile, File outDirectory){
		if(inFile.isFile()){	//拷贝文件
			return copyTextFile(inFile, new File(outDirectory.getAbsolutePath(),inFile.getName()));
		}else if(inFile.isDirectory()){	//拷贝目录及目录下的所有目录和文件
			int i = 0;
			outDirectory = new File(outDirectory.getAbsolutePath(),inFile.getName());
			if (!outDirectory.exists()){
				outDirectory.mkdirs();
				if(log.isDebugEnabled()){
					log.debug("拷贝当前目录完成！从["+inFile.getPath()+"]到["+outDirectory.getPath()+"]");
				}
			}
			File[] files = inFile.listFiles(new MyFileFilter());	//设置文件过滤
			for (File f:files) {
				i += copyTextFiles(f,outDirectory);
			}
			return i;
		}
		return 0;
	}

	/**
	 * 拷贝单个源文件到目标文件（按文本的方式拷贝并覆盖）先通过InputStreamReader将输入流转换成Reader,可设置编码转换
	 * @param src 输入文件
	 * @param des 输出文件
	 * @return 0 未拷贝任何文件，>=1 拷贝的文件数（不包括目录）
	 */
	private static int copyTextFile(File src, File des){
		try {
			//创建目标文件(不需要这步,加上也可以)
			if (!des.exists()) des.createNewFile();
			//获取输入文件
			Reader in = new BufferedReader(new InputStreamReader(new FileInputStream(src)));
			//设定输出文件的编码
//			String encodingUse = ((encoding == null) ? DEFAULT_ENCODING : encoding);
			Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(des)));
			//设置读取缓冲区，并进行读取写入
			char[] buffer = new char[4096];
			int readBytes = -1;
			while ((readBytes = in.read(buffer)) != -1) {
				out.write(buffer, 0, readBytes);
			}
			//关闭输入输出流
			out.flush();
			out.close();
			in.close();
			if(log.isDebugEnabled()){
				log.debug("拷贝当前文件完成！从["+src.getPath()+"]到["+des.getPath()+"]");
			}
		} catch (FileNotFoundException e) {
			log.error("拷贝文件时发生文件路径找不到异常，路径是src:[" + src + "]des:[" + des + "]", e);
			return 0;
		} catch (IOException e) {
			log.error("拷贝文件时发生IO异常，路径是src:[" + src + "]des:[" + des + "]", e);
			return 0;
		}
		return 1;
	}
	
	public static void main(String[] args) {
		//boolean ok = tVar.copyFile("F:\\Say You Say Me.mp3","F:\\mp3\\Say You Say Me.mp3");
		//boolean ok = tVar.copyFile("F:\\WebLogic 8.1 config.bmp","\\\\192.168.70.251\\刻录区\\WebLogic 8.1 config.bmp");
		//boolean ok = tVar.copyFile("F:\\1.2-1424-0T15-3A.exe","\\\\192.168.70.251\\刻录区\\1.2-1424-0T15-3A.exe");
		int i = CopyFile.copyTextFiles("D:/dev/otherwork/codeutil/src/main/resources/",OUT_PATH);
		System.out.println("拷贝的文件个数是：" + i);
	}

}
